<template>
  <div class="out-div">
    <el-row class="drag">
      <el-col :span="23">{{this.$store.state.User.userAlias}}</el-col>
      <el-col :span="1">
        <i @click="exit" class="el-icon-close no-drag"></i>
      </el-col>
    </el-row>
    <el-row :gutter="5" class="inner">
      <el-col :span="4">
        <user-list :list="users" @choose="chooseUser"></user-list>
      </el-col>
      <el-col :span="20">
        <message-information></message-information>
        <input-box :user="currentDialogUser"></input-box>
      </el-col>
    </el-row>
  </div>
</template>
<script>
import InputBox from "./DialogPage/InputBox";
import MessageInformation from "./DialogPage/MessageInformation";
import UserList from "./DialogPage/UserList";
const net = require("net");
import {
  MsgHeader,
  MsgType,
  SmsReq,
  UserStatus,
  UserInfoResp,
  FileDownloadNotice,
  FileDownloadReq,
  FileDownloadRes
} from "../security_msg_pb";
const remote = require("electron").remote;
const ipc = require("electron").ipcRenderer;
const fs = require("fs");
const crypto = require("crypto");
const { Writable } = require("stream");
import { UserStatusEvent, DownloadEvent } from "../smss_socket_event";
export default {
  components: { InputBox, MessageInformation, UserList },
  created() {
    if (this.$socket.pending) {
      // 如果连接断开则重启应用
      ipc.send("restart");
    } else {
      ipc.send("create-tray");
      remote.getCurrentWindow().setSize(945, 600);
      remote.getCurrentWindow().center();
      this.$nextTick(() => {
        this.$socket.on("data", data => {
          this.onData(data);
        });
        setTimeout(() => {
          new UserStatusEvent(
            this.$socket,
            this.$store.state.User.userID,
            this.$store.state.User.userToken
          ).then(userStatus => {
            this.onUserStatusNotice(userStatus);
          });
        }, 1000);
      });
    }
  },
  data() {
    return {
      users: [],
      currentDialogUser: { id: 0, name: "" },
      streamClient: null
    };
  },
  methods: {
    exit() {
      ipc.send("hide");
    },
    // 选择的用户
    chooseUser(alias, id) {
      this.currentDialogUser.name = alias;
      this.currentDialogUser.id = id;
    },
    // 请求当前已经在线的用户
    requestUserStatus() {
      let msgHeader = new MsgHeader();
      msgHeader.setFrom(this.$store.state.User.userID);
      msgHeader.setTo(0);
      msgHeader.setMsgSize(0);
      msgHeader.setMsgType(MsgType.USER_STATUS_REQ);
      msgHeader.setToken(this.$store.state.User.userToken);
      const headerBuffer = msgHeader.serializeBinary();
      let packageHeader = Buffer.alloc(8);
      packageHeader.write("AB47");
      packageHeader.writeInt32LE(headerBuffer.length, 4);
      const packageBuffer = Buffer.concat([packageHeader, headerBuffer]);
      this.$socket.write(packageBuffer);
    },
    onData(data) {
      // 处理粘包，循环读取
      let readSize = 0;
      while (readSize < data.length) {
        let flag = data.toString("utf8", readSize, readSize + 4);
        if (flag !== "AB47") {
          readSize += 4;
          continue;
        }
        readSize += 4;
        let headerSize = data.readInt32LE(readSize);
        readSize += 4;
        // 消息头反向序列化
        let msgHeader = MsgHeader.deserializeBinary(
          data.subarray(readSize, headerSize + readSize)
        );
        readSize += headerSize;
        // 消息类型
        let msgType = msgHeader.getMsgType();
        // 消息大小
        let msgSize = msgHeader.getMsgSize();
        switch (msgType) {
          case MsgType.USER_INFO_RESP:
            this.onUserInfoResp(
              UserInfoResp.deserializeBinary(
                data.subarray(readSize, msgSize + readSize)
              )
            );
            break;
          case MsgType.USER_STATUS_NOTICE:
            this.onUserStatusNotice(
              UserStatus.deserializeBinary(
                data.subarray(readSize, msgSize + readSize)
              )
            );
            break;
          case MsgType.MSG_SEND_REQ:
            this.onSmsSendReq(data.subarray(readSize, msgSize + readSize));
            break;
          case MsgType.FILE_DOWNLOAD_NOTICE:
            new DownloadEvent(
              this.$store.state.User.userID,
              this.$store.state.User.userToken,
              msgHeader,
              FileDownloadNotice.deserializeBinary(
                data.subarray(readSize, msgSize + readSize)
              )
            );
            break;
          default:
        }
        readSize += msgSize;
      }
    },
    onUserStatusNotice(userStatus) {
      let statusList = userStatus.getStatusListList();
      for (let i = 0; i < statusList.length; i++) {
        if (statusList[i].getIsOnLine()) {
          for (let j = 0; j < this.users.length; j++) {
            if (this.users[j].name === statusList[i].getAlias()) {
              return;
            }
          }
          this.users.push({
            name: statusList[i].getAlias(),
            id: statusList[i].getUserId(),
            online: true
          });
        }
        if (!statusList[i].getIsOnLine()) {
          for (let j = 0; j < this.users.length; j++) {
            if (this.users[j].name === statusList[i].getAlias()) {
              this.users[j].online = false;
              return;
            }
          }
        }
      }
    },
    onUserInfoResp(userInfoResp) {
      if (userInfoResp.getPubKey() !== "") {
        fs.writeFile(
          "data/.shadow/pub/" + userInfoResp.getUserId() + ".pem",
          userInfoResp.getPubKey(),
          err => {
            if (err) throw err;
          }
        );
      }
    },
    onSmsSendReq(cipherText) {
      fs.readFile("data/.shadow/mine.pem", (err, prv_key) => {
        let text = crypto.privateDecrypt(
          {
            key: prv_key.toString(),
            padding: crypto.constants.RSA_PKCS1_PADDING
          },
          cipherText
        );
        let smsReq = SmsReq.deserializeBinary(text);
        console.log(">>>>>" + smsReq.getText());
      });
    }
  }
};
</script>
<style scroped>
.out-div {
  width: 100%;
  height: 100%;
  background-color: rgb(235, 235, 235);
  border-radius: 5px 5px 5px 5px;
}
.drag {
  -webkit-app-region: drag;
  margin-bottom: 5px;
  background-color: rgb(168, 168, 188);
  border-radius: 5px 5px 0 0;
  height: 40px;
  line-height: 40px;
  color: white;
  padding-left: 10px;
}
.no-drag {
  -webkit-app-region: no-drag;
}
.inner {
  height: 550px;
  padding: 5px;
}
</style>